﻿//////////////////////////////////////////////////////////////////
//
// Helen\Program.cs
//
// Copyright (c) 2012 Dan Pike.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using Interfaces;
using System;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Utilities;

namespace Helen
{
   static class Program
   {
      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// 
      /// </summary>
      public static Form MainForm;
      public static Logger Logger;
      public static Configuration AppConfig;
      public static Config.Helen Settings;
      public static Utilities.Config.Utilities UtilitiesSettings;
      public static string SenderId = Identifiers.Helen;
      public static EventWaitHandle ProgramRunning;

      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         bool createdNew = false;
         try
         {
            // Prevent duplication
            using (ProgramRunning = new EventWaitHandle(false, EventResetMode.ManualReset, SenderId, out createdNew))
            {
               if (!createdNew)
               {
                  MessageBox.Show(string.Concat(Application.ProductName, " is already running, this will now close"),
                     Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                  return;
               }

               // Load the configuration
               AppConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
               UtilitiesSettings = AppConfig.GetSection(Utilities.Config.Utilities.CONFIG_SECTION) as Utilities.Config.Utilities;
               Settings = AppConfig.GetSection(Config.Helen.CONFIG_SECTION) as Config.Helen;
               if (null == Settings)
               {
                  Settings = new Config.Helen();
                  AppConfig.Sections.Add(Config.Helen.CONFIG_SECTION, Settings);
                  AppConfig.Save(ConfigurationSaveMode.Full);
               }

               // Start the debug logging
               Logger = new Logger();

               // Create the main form but don't display it, yet
               Application.EnableVisualStyles();
               Application.SetCompatibleTextRenderingDefault(false);
               MainForm = new Main();

               // Start up the GUI
               Application.Run(MainForm);

               Logger.DebugFormat("saving configuration changes");
               AppConfig.Save(ConfigurationSaveMode.Full);

#if DEBUG
               // Copy it back up to prevent losing it when VS2010 overwrites it
               if (AppConfig.FilePath.EndsWith(".vshost.exe.Config", StringComparison.CurrentCultureIgnoreCase))
               {
                  string sourceFile = Path.Combine(
                     Path.GetDirectoryName(AppConfig.FilePath),
                     "..", "..", Application.ProductName,
                     "app.config"
                     );
                  if (File.Exists(sourceFile) && (0 == (File.GetAttributes(sourceFile) & FileAttributes.ReadOnly)))
                  {
                     File.Copy(AppConfig.FilePath, sourceFile, true);
                  }
               }
#endif
            }
         }
         catch (Exception ex)
         {
            // We didn't catch the exception
            if (null != Logger)
            {
               // Yippee! The logger exists, so we can dump the call stack
               Logger.Exception(ex);
            }

            MessageBox.Show(
               string.Concat(Application.ProductName, " threw an exception: ", ex.Message),
               Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
         }
         finally
         {
            if (null != Logger)
            {
               Logger.DebugFormat("{0} is exiting", Application.ProductName);
            }
         }
      }
   }
}
